package com.gamefx.fte
{
	import flash.text.engine.ContentElement;
	import flash.text.engine.ElementFormat;
	import flash.text.engine.FontDescription;
	import flash.text.engine.FontPosture;
	import flash.text.engine.FontWeight;
	import flash.text.engine.GraphicElement;
	import flash.text.engine.TextElement;
	import flash.utils.Dictionary;

	/**
	 * Convert text tool
	 * @author feather
	 */
	public class TextConverter
	{
		/**
		 * Conver HTML string to elements vector.
		 * Supprots: b,i,font(color,face,size),a(href),img(src,width,height)
		 * @param html
		 * @param defaultFormat
		 * @param graphicDict
		 * @return
		 */
		public static function conver(html:String, defaultFormat:Object = null, graphicDict:IGraphicDict = null):Vector.<ContentElement>
		{
			html = html.replace(/<br\s*\/?>/ig, '\n'); //将<br/>替换为换行符
			html = html.replace(/>([^<]+)</g, ">($1)<"); //将<TAG></TAG>中的内容用括号括起来，解决空格等字符被XML过滤的问题

			if (instance == null)
				instance = new TextConverter();
			instance.elements = new Vector.<ContentElement>();
			instance.linkData = new Dictionary(true);
			instance.graphicDict = graphicDict != null ? graphicDict : GraphicDict.getInstance();
			if (defaultFormat != null)
			{
				with (instance)
				{
					color = defaultFormat.hasOwnProperty('color') ? defaultFormat.color : 0x000000;
					fontSize = defaultFormat.hasOwnProperty('fontSize') ? defaultFormat.fontSize : 12;
					fontName = defaultFormat.hasOwnProperty('fontName') ? defaultFormat.fontName : "_serif";
					fontWeight = (defaultFormat.hasOwnProperty('fontWeight') && defaultFormat.fontWeight == "bold") ? "bold" : "normal";
					fontPosture = (defaultFormat.hasOwnProperty('fontPosture') && defaultFormat.fontWeight == "italic") ? "italic" : "normal";
				}
			}
			else
			{
				with (instance)
				{
					color = 0x000000;
					fontSize = 12;
					fontName = "_serif";
					fontWeight = "normal";
					fontPosture = "normal";
				}
			}
			try
			{
				instance.parseHtml(XML(html), []);
			}
			catch (e:*)
			{

			}
			var elements:Vector.<ContentElement> = instance.elements;
			instance.elements = null;
			instance.linkData = null;
			instance.graphicDict = null;
			return elements;
		}


		private static var instance:TextConverter;

		private var elements:Vector.<ContentElement>;
		private var linkData:Dictionary;
		private var graphicDict:IGraphicDict;

		private var color:uint;
		private var fontSize:int;
		private var fontName:String;
		private var fontWeight:String;
		private var fontPosture:String;

		private function parseHtml(xml:XML, parents:Array):void
		{
			var item:XML;
			var name:String;
			var text:String;
			var fontDescription:FontDescription;
			var elementFormat:ElementFormat;
			var graphicElement:GraphicElement;
			var textElement:TextElement;
			var parent:XML;
			var key:String;
			var parentsClone:Array;

			for each (item in xml.children())
			{
				if (item.hasComplexContent())
				{
					parentsClone = parents.slice();
					parentsClone.push(xml);
					parseHtml(item, parentsClone);
					continue;
				}

				name = String(item.localName()).toLowerCase();
				if (name == 'img') //图像
				{
					key = item.@src;
					if (graphicDict != null && graphicDict.hasItem(key))
					{
						graphicElement = new GraphicElement(graphicDict.getItem(key), Number(item.@width), Number(item.@height));
						for each (parent in parentsClone)
						{
							if (parent != null && String(parent.localName()).toLowerCase() == 'a')
							{
								if (graphicElement.userData == null)
									graphicElement.userData = {};
								linkData[parent] ? graphicElement.userData['data'] = linkData[parent] : graphicElement.userData['data'] = linkData[parent] = {href: String(parent.@href)};
								break;
							}
						}
						graphicElement.elementFormat = new ElementFormat();
						elements.push(graphicElement);
					}
					continue;
				}

				text = item.toString();
				if (text.length <= 2) //内容为空
				{
					continue;
				}

				text = text.slice(1, -1);
				fontDescription = new FontDescription(fontName, fontWeight, fontPosture);
				elementFormat = new ElementFormat(null, fontSize, color);
				textElement = new TextElement(text);

				parentsClone = parents.slice();
				name == null ? parentsClone.push(xml) : parentsClone.push(xml, item);

				for each (parent in parentsClone)
				{
					if (parent == null)
						continue;

					switch (String(parent.localName()).toLowerCase())
					{
						case 'b':
							fontDescription.fontWeight = FontWeight.BOLD;
							break;
						case 'i':
							fontDescription.fontPosture = FontPosture.ITALIC;
							break;
						case 'font':
							if (parent.@color != undefined)
								elementFormat.color = uint(String(parent.@color).replace('#', '0x'));
							if (parent.@face != undefined)
								fontDescription.fontName = String(parent.@face);
							if (parent.@size != undefined)
								elementFormat.fontSize = Number(parent.@size);
							break;
						case 'a':
							if (textElement.userData == null)
								textElement.userData = {};
							linkData[parent] ? textElement.userData['data'] = linkData[parent] : textElement.userData['data'] = linkData[parent] = {href: String(parent.@href)};
							break;
					}
				}

				elementFormat.fontDescription = fontDescription;
				textElement.elementFormat = elementFormat;
				elements.push(textElement);
			}
		}

	}
}